﻿using System;
using System.Buffers;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Daq.Utils
{
    /// <summary>
    /// 基于Span<char>的高性能字符串拼接工具
    /// 适合高频调用场景，减少内存分配和GC压力
    /// </summary>
    public ref struct SpanStringJoiner : IDisposable
    {
        private char[] _buffer;       // 从数组池租用的字符缓冲区
        private Span<char> _span;     // 缓冲区的Span视图
        private int _position;        // 当前写入位置
        private const int DefaultCapacity = 128;  // 默认初始容量

        /// <summary>
        /// 初始化拼接器
        /// </summary>
        public SpanStringJoiner(int initialCapacity = DefaultCapacity)
        {
            _buffer = ArrayPool<char>.Shared.Rent(initialCapacity);
            _span = _buffer.AsSpan();
            _position = 0;
        }

        /// <summary>
        /// 拼接字符串
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Append(string value)
        {
            if (string.IsNullOrEmpty(value)) return;

            EnsureCapacity(value.Length);
            value.CopyTo(_span.Slice(_position));
            _position += value.Length;
        }

        /// <summary>
        /// 拼接数值类型（支持所有实现ISpanFormattable的类型）
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Append<T>(T value) where T : struct, ISpanFormattable
        {
            // 预留32个字符空间（足够大多数数值类型使用）
            EnsureCapacity(32);

            if (value.TryFormat(_span.Slice(_position), out int written, format: default, provider: CultureInfo.CurrentCulture))
            {
                _position += written;
            }
            else
            {
                // 极端情况下扩容后重试
                EnsureCapacity(64); // 更大的预留空间
                if (!value.TryFormat(_span.Slice(_position), out written, format: default, provider: CultureInfo.CurrentCulture))
                {
                    throw new InvalidOperationException("数值格式化失败，缓冲区不足");
                }
                _position += written;
            }
        }

        /// <summary>
        /// 确保缓冲区有足够空间
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private void EnsureCapacity(int requiredLength)
        {
            if (_position + requiredLength <= _span.Length) return;

            // 计算新容量（取当前容量的2倍或所需总容量，取较大值）
            int newCapacity = Math.Max(_span.Length * 2, _position + requiredLength);
            char[] newBuffer = ArrayPool<char>.Shared.Rent(newCapacity);

            // 复制原有数据到新缓冲区
            _span.Slice(0, _position).CopyTo(newBuffer);

            // 归还旧缓冲区，更新引用
            ArrayPool<char>.Shared.Return(_buffer);
            _buffer = newBuffer;
            _span = newBuffer.AsSpan();
        }

        /// <summary>
        /// 完成拼接并返回结果字符串（同时释放资源）
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public string ToStringAndRelease()
        {
            string result = new string(_span.Slice(0, _position));
            Dispose();
            return result;
        }

        /// <summary>
        /// 释放缓冲区（归还到数组池）
        /// </summary>
        public void Dispose()
        {
            if (_buffer != null)
            {
                ArrayPool<char>.Shared.Return(_buffer);
                _buffer = null;
                _span = default;
                _position = 0;
            }
        }
    }
}
